1 Requirements

2 Sample overview

2.1 Data import

  • Checking if result file(s) are available:
  • Importing result table(s):
[1] "Import of counts table complete."

2.2 Sample table

  • overview of samples

3 Quality control

3.1 Total number of mapped reads per sample

  • figure shows the total number of mapped reads used for fitness score calculation
  • all other reads that were filtered out during preprocessing (low quality, low mapping score) are not included

3.2 Number of individual barcodes per sample

  • figure shows the number of individual, unique barcodes per sample
  • depnding on bowtie settings, a certain number of mismatches in barcodes are allowed

3.3 Number of missing barcodes per sample

  • figure shows the number of missing barcodes per sample
  • this number is determined from the number of total encountered barcodes across all samples

3.4 Number of barcodes per gene, per sample

  • figure shows the number of barcodes per gene, per sample
  • the x-axis shows the number of genes with N barcodes, broken down by sample
  • barcodes without mapped reads for the respective sample are removed
  • for example a colored bar with label ≤ 2 shows number of genes with less or equal than 2 barcodes

3.5 Read count distribution, violin plot

  • figure shows the read count distribution per sample and barcode
  • read count per barcode is only shown for the first 1000 barcodes to reduce processing time
  • barcodes without mapped reads for the respective sample are removed
  • read count is log 10 transformed (0 -> 1, 1 -> 10, 2 -> 100, …)

3.6 Read count distribution, histogram

  • figure shows the same data as above, but with full set of barcodes per sample
  • barcodes without mapped reads for the respective sample are removed
  • read count is log 10 transformed (0 -> 1, 1 -> 10, 2 -> 100, …)

3.7 Top 10 most abundant barcodes, per sample

  • figure shows top 10 barcodes ranked by read count
  • ideally, initial time point samples show high equality of barcode abundance
  • extremely high abundance of very few barcodes is a sign of few mutants outcompeting the population
  • this can happen when libraries are (pre-) cultivated for too long periods of time
  • can lead to downstream problems as it reduces library diversity (depletes low abundant mutants)

3.8 Cumulative read count distribution and barcode diversity

  • figure shows the barcode diversity by plotting fraction of reads (%) vs fraction of barcodes (%)
  • the ideal library has high diversity and equal distribution of barcodes for initial time points
  • such a distribution would follow the diagonal dashed grey line
  • if reads per barcode (red line) are not well distributed, % of reads (y-axis) shows a steep ascent
  • this means very few barcodes contribute to almost all reads

  • this table shows the area under curve (AUC) for the line plot above
  • an AUC of 0.5 is ideal, an AUC approaching 1.0 is not optimal
  • the ‘Gini index’ is a score between 0 and 1 measuring population equality
  • it is defined as the (AUC - AUC_optimal) / AUC_optimal
  • a Gini score of 0 describes a perfectly equal, a Gini score of 1.0 a perfectly unequal distribution

3.9 Sample and replicate correlation coefficent (R)

  • figure shows heat map with correlation coefficient R (-1 < R < 1)
  • correlation coefficient shows how strongly read abundance is correlated

3.10 Sample and replicate similarity with PCA

  • this figure shows sample similarity similar to above figure
  • uses principal component analysis (PCA) to reduce the multidimensional data to 3 main dimensions
  • plotted are principal component 1 (x-axis), 2 (y-axis) and 3 (point size)
  • replicates for same samples should cluster together
  • outliers should be easily visible

4 Report info

The template for this report is located in ./nf-core-crispriscreen/bin/counts_summary.Rmd.

Date: 2024-04-10

Author: Michael Jahn, PhD

Affilations:

5 Session Info

R version 4.3.3 (2024-02-29)
Platform: x86_64-conda-linux-gnu (64-bit)
Running under: Ubuntu 20.04.6 LTS

Matrix products: default
BLAS/LAPACK: /conda-env/fitness/lib/libopenblasp-r0.3.27.so;  LAPACK version 3.12.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
[10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

time zone: NA
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] Hmisc_5.1-2   tidyr_1.3.1   ggplot2_3.5.0 dplyr_1.1.4  

loaded via a namespace (and not attached):
 [1] sass_0.4.9        utf8_1.2.4        generics_0.1.3    stringi_1.8.3    
 [5] digest_0.6.35     magrittr_2.0.3    evaluate_0.23     grid_4.3.3       
 [9] fastmap_1.1.1     jsonlite_1.8.8    nnet_7.3-19       backports_1.4.1  
[13] Formula_1.2-5     gridExtra_2.3     purrr_1.0.2       fansi_1.0.6      
[17] scales_1.3.0      jquerylib_0.1.4   cli_3.6.2         rlang_1.1.3      
[21] munsell_0.5.1     base64enc_0.1-3   withr_3.0.0       cachem_1.0.8     
[25] yaml_2.3.8        tools_4.3.3       checkmate_2.3.0   htmlTable_2.4.2  
[29] colorspace_2.1-0  vctrs_0.6.5       R6_2.5.1          rpart_4.1.23     
[33] lifecycle_1.0.4   stringr_1.5.1     htmlwidgets_1.6.4 foreign_0.8-86   
[37] cluster_2.1.6     pkgconfig_2.0.3   pillar_1.9.0      bslib_0.7.0      
[41] gtable_0.3.4      glue_1.7.0        data.table_1.15.2 highr_0.10       
[45] xfun_0.43         tibble_3.2.1      tidyselect_1.2.0  rstudioapi_0.16.0
[49] knitr_1.46        farver_2.1.1      htmltools_0.5.8.1 rmarkdown_2.26   
[53] labeling_0.4.3    compiler_4.3.3   
LS0tCnRpdGxlOiBSZWFkIGNvdW50cyBzdW1tYXJ5CmF1dGhvcjogJ1NZU1RFTTogYHIgdmVyc2lvblsxM11gJwpkYXRlOiAnREFURTogYHIgU3lzLnRpbWUoKWAnCnBhcmFtczoKICBjcHVzOiAyCiAgYXJ0aWZhY3RfZGlyOiBhcnRpZmFjdHMKICBpbnB1dF9kaXI6IC4vCiAgbWV0YToKICAgIHZhbHVlOgogICAgICBpZDogY291bnRzX3N1bW1hcnkKICB0ZXN0OiBzb21ldmFsdWUKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogY29zbW8KICAgIHRvYzogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSkKYGBgCgojIFJlcXVpcmVtZW50cwoKLSBsb2FkaW5nIGxpYnJhcmllcyBgZHBseXJgLCBgZ2dwbG90MmAsIGB0aWR5cmAsIGBIbWlzY2AKCmBgYHtyfQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMoewogICAgbGlicmFyeShnckRldmljZXMpCiAgICBsaWJyYXJ5KGRwbHlyKQogICAgbGlicmFyeShnZ3Bsb3QyKQogICAgbGlicmFyeSh0aWR5cikKICAgIGxpYnJhcnkoSG1pc2MpCn0pCmBgYAoKIyBTYW1wbGUgb3ZlcnZpZXcKCiMjIERhdGEgaW1wb3J0CgotIENoZWNraW5nIGlmIHJlc3VsdCBmaWxlKHMpIGFyZSBhdmFpbGFibGU6CgpgYGB7cn0KIyBnZXQgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeQp3ZCA8LSBnZXR3ZCgpCmlucHV0X3BhdHRlcm4gPC0gImFsbF9jb3VudHMudHN2IgoKIyBjaGVjayBpbnB1dCBmaWxlcyBhbmQgY29tcGlsZSBzbWFsbCB0YWJsZQppbnB1dF9maWxlcyA8LSBncmVwKGxpc3QuZmlsZXMod2QpLCBwYXR0ZXJuID0gaW5wdXRfcGF0dGVybiwgdmFsdWUgPSBUUlVFKQppZiAobGVuZ3RoKGlucHV0X2ZpbGVzKSA9PSAxKSB7CiAgICBkZl9pbnB1dCA8LSBiaW5kX2NvbHMoCiAgICAgICAgZGF0YS5mcmFtZShpbnB1dF9maWxlcyksCiAgICAgICAgZmlsZS5pbmZvKHBhc3RlKHdkLCBpbnB1dF9maWxlcywgc2VwID0gIi8iKSkKICAgICkgJT4lCiAgICAgICAgbXV0YXRlKHNpemUgPSBwYXN0ZShzaXplIC8gMWU2LCAiTUIiKSkKICAgIHJvd25hbWVzKGRmX2lucHV0KSA8LSBOVUxMCiAgICBkZl9pbnB1dFtjKDEsIDIsIDMsIDQsIDUsIDEwKV0KfSBlbHNlIHsKICAgIHN0b3AocGFzdGUwKCJSZXF1aXJlZCBpbnB1dCBmaWxlKHMpICciLCBpbnB1dF9wYXR0ZXJuLCAiJyB3ZXJlIG5vdCBmb3VuZC4iKSkKfQpgYGAKCi0gSW1wb3J0aW5nIHJlc3VsdCB0YWJsZShzKToKCmBgYHtyfQojIGxvYWQgY291bnRzIG1hdHJpeApkZl9jb3VudHMgPC0gcmVhZC5kZWxpbShwYXN0ZTAod2QsICIvIiwgaW5wdXRfcGF0dGVybikpCmRmX2NvdW50cyA8LSB0aWR5cjo6cGl2b3RfbG9uZ2VyKGRmX2NvdW50cywKICAgIGNvbHMgPSAzOm5jb2woZGZfY291bnRzKSwKICAgIG5hbWVzX3RvID0gInNhbXBsZSIsIHZhbHVlc190byA9ICJuX3JlYWRzIgopCiMgc29ydApkZl9jb3VudHMgPC0gYXJyYW5nZShkZl9jb3VudHMsIHNhbXBsZSkKcHJpbnQoIkltcG9ydCBvZiBjb3VudHMgdGFibGUgY29tcGxldGUuIikKYGBgCgojIyBTYW1wbGUgdGFibGUKCi0gb3ZlcnZpZXcgb2Ygc2FtcGxlcwoKYGBge3J9CiMgbGlzdCBvZiBzYW1wbGVzICsgZ2VuZXJpYyBvcHRpb25zCmxpc3Rfc2FtcGxlcyA8LSB1bmlxdWUoZGZfY291bnRzJHNhbXBsZSkKZmlnd2lkdGggPC0gOQpmaWdoZWlnaHQgPC0gcm91bmQoMSArIChsZW5ndGgobGlzdF9zYW1wbGVzKSAvIDQpKQpmaWdoZWlnaHQyIDwtIDEuNiAqIGZpZ2hlaWdodAoKIyBvdXRwdXQgc2FtcGxlIHRhYmxlCnRlc3QgPC0gZGZfY291bnRzICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKAogICAgICAgIGJhcmNvZGVzID0gbGVuZ3RoKHVuaXF1ZShzZ1JOQSkpLAogICAgICAgIHRvdGFsX3JlYWRzID0gc3VtKG5fcmVhZHMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgbWluX3JlYWRzID0gbWluKG5fcmVhZHMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgbWVhbl9yZWFkcyA9IG1lYW4obl9yZWFkcywgbmEucm0gPSBUUlVFKSwKICAgICAgICBtYXhfcmVhZHMgPSBtYXgobl9yZWFkcywgbmEucm0gPSBUUlVFKSwKICAgICkKYGBgCgojIFF1YWxpdHkgY29udHJvbAoKYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0KIyBkZWZpbmUgYSBjdXN0b20gZ2dwbG90MiB0aGVtZSAoanVzdCBmb3IgcHJldHRpbmVzcykKIyBjdXN0b20gZ2dwbG90MiB0aGVtZSB0aGF0IGlzIHJldXNlZCBmb3IgYWxsIGxhdGVyIHBsb3RzCmN1c3RvbV9jb2xvcnMgPC0gYygiI0U3Mjk4QSIsICIjNjZBNjFFIiwgIiNFNkFCMDIiLCAiIzc1NzBCMyIsICIjQjNCM0IzIiwgIiMxQjlFNzciLCAiI0Q5NUYwMiIsICIjQTY3NjFEIikKY3VzdG9tX3JhbmdlIDwtIGZ1bmN0aW9uKG4gPSA1KSB7CiAgICBjb2xvclJhbXBQYWxldHRlKGN1c3RvbV9jb2xvcnNbYygxLCA1LCAyKV0pKG4pCn0KCmN1c3RvbV90aGVtZSA8LSBmdW5jdGlvbihiYXNlX3NpemUgPSAxMiwgYmFzZV9saW5lX3NpemUgPSAxLjAsIGJhc2VfcmVjdF9zaXplID0gMS4wLCAuLi4pIHsKICAgIHRoZW1lX2xpZ2h0KGJhc2Vfc2l6ZSA9IGJhc2Vfc2l6ZSwgYmFzZV9saW5lX3NpemUgPSBiYXNlX2xpbmVfc2l6ZSwgYmFzZV9yZWN0X3NpemUgPSBiYXNlX3JlY3Rfc2l6ZSkgKyB0aGVtZSgKICAgICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBncmV5KDAuNCksIHNpemUgPSAxMCksCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMTIsIDEyLCAxMiwgMTIpLCAicG9pbnRzIiksCiAgICAgICAgYXhpcy50aWNrcy5sZW5ndGggPSB1bml0KDAuMiwgImNtIiksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBncmV5KDAuNCksIGxpbmV0eXBlID0gInNvbGlkIiwgbGluZWVuZCA9ICJyb3VuZCIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IGdyZXkoMC40KSwgc2l6ZSA9IDEwKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBncmV5KDAuNCksIHNpemUgPSAxMCksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplID0gMC42LCBsaW5ldHlwZSA9ICJzb2xpZCIsIGNvbG91ciA9IGdyZXkoMC45KSksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QobGluZXR5cGUgPSAic29saWQiLCBjb2xvdXIgPSBncmV5KDAuNCksIGZpbGwgPSBOQSwgc2l6ZSA9IDEuMCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gZ3JleSgwLjQpLCBzaXplID0gMTAsIG1hcmdpbiA9IHVuaXQocmVwKDMsIDQpLCAicG9pbnRzIikpLAogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9IGdyZXkoMC40KSwgc2l6ZSA9IDEwKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgLi4uCiAgICApCn0KCiMgZnVuY3Rpb24gdG8gZXhwb3J0IGFuIGltYWdlIGFzIHN2ZyBhbmQgcG5nCnNhdmVfcGxvdCA8LSBmdW5jdGlvbihwbCwgcGF0aCA9ICIiLCB3aWR0aCA9IDYsIGhlaWdodCA9IDYpIHsKICAgIHBsX25hbWUgPC0gZGVwYXJzZShzdWJzdGl0dXRlKHBsKSkKICAgIHBkZigKICAgICAgICBmaWxlID0gcGFzdGUwKHBhdGgsIHBsX25hbWUsICIucGRmIiksCiAgICAgICAgd2lkdGggPSB3aWR0aCwgaGVpZ2h0ID0gaGVpZ2h0CiAgICApCiAgICBwcmludChwbCkKICAgIGRldi5vZmYoKQogICAgZ3JEZXZpY2VzOjpzdmcoCiAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAocGF0aCwgcGxfbmFtZSwgIi5zdmciKSwKICAgICAgICB3aWR0aCA9IHdpZHRoLCBoZWlnaHQgPSBoZWlnaHQKICAgICkKICAgIHByaW50KHBsKQogICAgZGV2Lm9mZigpCiAgICBnckRldmljZXM6OnBuZygKICAgICAgICBmaWxlbmFtZSA9IHBhc3RlMChwYXRoLCBwbF9uYW1lLCAiLnBuZyIpLAogICAgICAgIHdpZHRoID0gd2lkdGggKiAxMjUsIGhlaWdodCA9IGhlaWdodCAqIDEyNSwgcmVzID0gMTIwCiAgICApCiAgICBwcmludChwbCkKICAgIGludmlzaWJsZShjYXB0dXJlLm91dHB1dChkZXYub2ZmKCkpKQp9CmBgYAoKIyMgVG90YWwgbnVtYmVyIG9mIG1hcHBlZCByZWFkcyBwZXIgc2FtcGxlCgotIGZpZ3VyZSBzaG93cyB0aGUgdG90YWwgbnVtYmVyIG9mIG1hcHBlZCByZWFkcyB1c2VkIGZvciBmaXRuZXNzIHNjb3JlIGNhbGN1bGF0aW9uCi0gYWxsIG90aGVyIHJlYWRzIHRoYXQgd2VyZSBmaWx0ZXJlZCBvdXQgZHVyaW5nIHByZXByb2Nlc3NpbmcgKGxvdyBxdWFsaXR5LCBsb3cgbWFwcGluZyBzY29yZSkgYXJlIG5vdCBpbmNsdWRlZAoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfdG90YWxfbWFwcGVkX3JlYWRzIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OnN1bW1hcml6ZShuX3JlYWRzID0gc3VtKG5fcmVhZHMpKSAlPiUKICAgIGdncGxvdChhZXMoeCA9IHNhbXBsZSwgeSA9IG5fcmVhZHMpKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgZ2VvbV9jb2woZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sIGFscGhhID0gMC43KSArCiAgICBsYWJzKHggPSAiIiwgeSA9ICJ0b3RhbCBudW1iZXIgb2YgbWFwcGVkIHJlYWRzIikgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X3RvdGFsX21hcHBlZF9yZWFkcywgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X3RvdGFsX21hcHBlZF9yZWFkcykKYGBgCgojIyBOdW1iZXIgb2YgaW5kaXZpZHVhbCBiYXJjb2RlcyBwZXIgc2FtcGxlCgotIGZpZ3VyZSBzaG93cyB0aGUgbnVtYmVyIG9mIGluZGl2aWR1YWwsIHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlCi0gZGVwbmRpbmcgb24gYGJvd3RpZWAgc2V0dGluZ3MsIGEgY2VydGFpbiBudW1iZXIgb2YgbWlzbWF0Y2hlcyBpbiBiYXJjb2RlcyBhcmUgYWxsb3dlZAoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfaW5kaXZpZHVhbF9iYXJjb2RlcyA8LSBkZl9jb3VudHMgJT4lCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2FtcGxlKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoYHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlYCA9IHN1bShuX3JlYWRzID4gMCkpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlLCB5ID0gYHVuaXF1ZSBiYXJjb2RlcyBwZXIgc2FtcGxlYCkpICsKICAgIGdlb21fY29sKGZpbGwgPSBjdXN0b21fY29sb3JzWzFdLCBhbHBoYSA9IDAuNykgKwogICAgbGFicyh4ID0gIiIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfaW5kaXZpZHVhbF9iYXJjb2Rlcywgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X2luZGl2aWR1YWxfYmFyY29kZXMpCmBgYAoKIyMgTnVtYmVyIG9mIG1pc3NpbmcgYmFyY29kZXMgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdGhlIG51bWJlciBvZiBtaXNzaW5nIGJhcmNvZGVzIHBlciBzYW1wbGUKLSB0aGlzIG51bWJlciBpcyBkZXRlcm1pbmVkIGZyb20gdGhlIG51bWJlciBvZiB0b3RhbCBlbmNvdW50ZXJlZCBiYXJjb2RlcyBhY3Jvc3MgYWxsIHNhbXBsZXMKCmBgYHtyLCBmaWcud2lkdGggPSBmaWd3aWR0aCwgZmlnLmhlaWdodCA9IGZpZ2hlaWdodCwgd2FybmluZyA9IEZBTFNFfQpwbG90X21pc3NpbmdfYmFyY29kZXMgPC0gZGZfY291bnRzICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGBtaXNzaW5nIGJhcmNvZGVzIHBlciBzYW1wbGVgID0gc3VtKG5fcmVhZHMgPT0gMCkpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlLCB5ID0gYG1pc3NpbmcgYmFyY29kZXMgcGVyIHNhbXBsZWApKSArCiAgICBnZW9tX2NvbChmaWxsID0gY3VzdG9tX2NvbG9yc1sxXSwgYWxwaGEgPSAwLjcpICsKICAgIGxhYnMoeCA9ICIiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X21pc3NpbmdfYmFyY29kZXMsIHdpZHRoID0gZmlnd2lkdGgsIGhlaWdodCA9IGZpZ2hlaWdodCkKcHJpbnQocGxvdF9taXNzaW5nX2JhcmNvZGVzKQpgYGAKCiMjIE51bWJlciBvZiBiYXJjb2RlcyBwZXIgZ2VuZSwgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdGhlIG51bWJlciBvZiBiYXJjb2RlcyBwZXIgZ2VuZSwgcGVyIHNhbXBsZQotIHRoZSB4LWF4aXMgc2hvd3MgdGhlIG51bWJlciBvZiBnZW5lcyB3aXRoIE4gYmFyY29kZXMsIGJyb2tlbiBkb3duIGJ5IHNhbXBsZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSBmb3IgZXhhbXBsZSBhIGNvbG9yZWQgYmFyIHdpdGggbGFiZWwgYOKJpCAyYCBzaG93cyBudW1iZXIgb2YgZ2VuZXMgd2l0aCBsZXNzIG9yIGVxdWFsIHRoYW4gMiBiYXJjb2RlcwoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CmRmX2JhcmNvZGVzX3Blcl9nZW5lIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpmaWx0ZXIobl9yZWFkcyA+IDApICU+JQogICAgZHBseXI6Omdyb3VwX2J5KHNhbXBsZSwgR2VuZSkgJT4lCiAgICBkcGx5cjo6c3VtbWFyaXplKGB1bmlxdWUgYmFyY29kZXNgID0gbGVuZ3RoKHVuaXF1ZShzZ1JOQSkpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoYHVuaXF1ZSBiYXJjb2Rlc2AgPSBjdXQoYHVuaXF1ZSBiYXJjb2Rlc2AsIGJyZWFrcyA9IHByZXR0eShgdW5pcXVlIGJhcmNvZGVzYCkpKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OmNvdW50KGB1bmlxdWUgYmFyY29kZXNgKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoYHVuaXF1ZSBiYXJjb2Rlc2AgPSBhcy5udW1lcmljKGdzdWIoIlxcKFswLTldKix8XFxdIiwgIiIsIGB1bmlxdWUgYmFyY29kZXNgKSkpICU+JQogICAgZHBseXI6OnVuZ3JvdXAoKSAlPiUKICAgIGRwbHlyOjphcnJhbmdlKHNhbXBsZSwgbikKCnBsb3RfYmFyY29kZXNfZ2VuZV9zYW1wbGUgPC0gZGZfYmFyY29kZXNfcGVyX2dlbmUgJT4lCiAgICBnZ3Bsb3QoYWVzKAogICAgICAgIHggPSBzYW1wbGUsIHkgPSBuLAogICAgICAgIGZpbGwgPSBmYWN0b3IoYHVuaXF1ZSBiYXJjb2Rlc2ApLAogICAgICAgIGxhYmVsID0gcGFzdGUwKCLiiaQgIiwgYHVuaXF1ZSBiYXJjb2Rlc2ApCiAgICApKSArCiAgICBnZW9tX2NvbChhbHBoYSA9IDAuNykgKwogICAgZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCBjb2xvciA9ICJ3aGl0ZSIpICsKICAgIGxhYnMoeCA9ICIiKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JSYW1wUGFsZXR0ZSgKICAgICAgICBjdXN0b21fY29sb3JzWzE6NV0pKGxlbmd0aCh1bmlxdWUoZGZfYmFyY29kZXNfcGVyX2dlbmVbWyJ1bmlxdWUgYmFyY29kZXMiXV0pKSkKICAgICkgKwogICAgY3VzdG9tX3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnNhdmVfcGxvdChwbG90X2JhcmNvZGVzX2dlbmVfc2FtcGxlLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQpCnByaW50KHBsb3RfYmFyY29kZXNfZ2VuZV9zYW1wbGUpCmBgYAoKIyMgUmVhZCBjb3VudCBkaXN0cmlidXRpb24sIHZpb2xpbiBwbG90CgotIGZpZ3VyZSBzaG93cyB0aGUgcmVhZCBjb3VudCBkaXN0cmlidXRpb24gcGVyIHNhbXBsZSBhbmQgYmFyY29kZQotIHJlYWQgY291bnQgcGVyIGJhcmNvZGUgaXMgb25seSBzaG93biBmb3IgdGhlIGZpcnN0IDEwMDAgYmFyY29kZXMgdG8gcmVkdWNlIHByb2Nlc3NpbmcgdGltZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSByZWFkIGNvdW50IGlzIGxvZyAxMCB0cmFuc2Zvcm1lZCAoMCAtPiAxLCAxIC0+IDEwLCAyIC0+IDEwMCwgLi4uKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0LCB3YXJuaW5nID0gRkFMU0V9CnBsb3RfY291bnRfZGlzdCA8LSBkZl9jb3VudHMgJT4lCiAgICBkcGx5cjo6ZmlsdGVyKG5fcmVhZHMgPiAwKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OnNsaWNlKDE6MTAwMCkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBzYW1wbGUsIHkgPSBsb2cxMChuX3JlYWRzKSkpICsKICAgIGdlb21fdmlvbGluKAogICAgICAgIHRyaW0gPSBGQUxTRSwgZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sCiAgICAgICAgYWxwaGEgPSAwLjcsIGNvbCA9ICJ3aGl0ZSIKICAgICkgKwogICAgbGFicyh5ID0gZXhwcmVzc2lvbigibG9nIlsxMF0gKiAiIHJlYWRzIHBlciBiYXJjb2RlIikpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NkbCwgZ2VvbSA9ICJwb2ludHJhbmdlIiwgc2l6ZSA9IDAuNSwgY29sID0gZ3JleSgwLjMpKSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfY291bnRfZGlzdCwgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0KQpwcmludChwbG90X2NvdW50X2Rpc3QpCmBgYAoKIyMgUmVhZCBjb3VudCBkaXN0cmlidXRpb24sIGhpc3RvZ3JhbQoKLSBmaWd1cmUgc2hvd3MgdGhlIHNhbWUgZGF0YSBhcyBhYm92ZSwgYnV0IHdpdGggZnVsbCBzZXQgb2YgYmFyY29kZXMgcGVyIHNhbXBsZQotIGJhcmNvZGVzIHdpdGhvdXQgbWFwcGVkIHJlYWRzIGZvciB0aGUgcmVzcGVjdGl2ZSBzYW1wbGUgYXJlIHJlbW92ZWQKLSByZWFkIGNvdW50IGlzIGxvZyAxMCB0cmFuc2Zvcm1lZCAoMCAtPiAxLCAxIC0+IDEwLCAyIC0+IDEwMCwgLi4uKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0Miwgd2FybmluZyA9IEZBTFNFfQpwbG90X3JlYWRzX3Blcl9iYyA8LSBkZl9jb3VudHMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBsb2cxMChuX3JlYWRzKSkpICsKICAgIGdlb21faGlzdG9ncmFtKGZpbGwgPSBjdXN0b21fY29sb3JzWzFdLCBhbHBoYSA9IDAuNywgYmlucyA9IDMwKSArCiAgICBsYWJzKHkgPSAiIiwgeCA9IGV4cHJlc3Npb24oImxvZyJbMTBdICogIiByZWFkcyBwZXIgYmFyY29kZSIpKSArCiAgICBmYWNldF93cmFwKH5zYW1wbGUsIG5jb2wgPSA0KSArCiAgICBjdXN0b21fdGhlbWUoKQoKc2F2ZV9wbG90KHBsb3RfcmVhZHNfcGVyX2JjLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQyKQpwcmludChwbG90X3JlYWRzX3Blcl9iYykKYGBgCgojIyBUb3AgMTAgbW9zdCBhYnVuZGFudCBiYXJjb2RlcywgcGVyIHNhbXBsZQoKLSBmaWd1cmUgc2hvd3MgdG9wIDEwIGJhcmNvZGVzIHJhbmtlZCBieSByZWFkIGNvdW50Ci0gaWRlYWxseSwgaW5pdGlhbCB0aW1lIHBvaW50IHNhbXBsZXMgc2hvdyBoaWdoIGVxdWFsaXR5IG9mIGJhcmNvZGUgYWJ1bmRhbmNlCi0gZXh0cmVtZWx5IGhpZ2ggYWJ1bmRhbmNlIG9mIHZlcnkgZmV3IGJhcmNvZGVzIGlzIGEgc2lnbiBvZiBmZXcgbXV0YW50cyBvdXRjb21wZXRpbmcgdGhlIHBvcHVsYXRpb24KLSB0aGlzIGNhbiBoYXBwZW4gd2hlbiBsaWJyYXJpZXMgYXJlIChwcmUtKSBjdWx0aXZhdGVkIGZvciB0b28gbG9uZyBwZXJpb2RzIG9mIHRpbWUKLSBjYW4gbGVhZCB0byBkb3duc3RyZWFtIHByb2JsZW1zIGFzIGl0IHJlZHVjZXMgbGlicmFyeSBkaXZlcnNpdHkgKGRlcGxldGVzIGxvdyBhYnVuZGFudCBtdXRhbnRzKQoKYGBge3IsIGZpZy53aWR0aCA9IGZpZ3dpZHRoLCBmaWcuaGVpZ2h0ID0gZmlnaGVpZ2h0Miwgd2FybmluZyA9IEZBTFNFfQpwbG90X3RvcDEwX2JhcmNvZGVzIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUpICU+JQogICAgZHBseXI6OmFycmFuZ2Uoc2FtcGxlLCBkZXNjKG5fcmVhZHMpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUocmFuayA9IHNlcV9hbG9uZyhzZ1JOQSkpICU+JQogICAgZHBseXI6OmZpbHRlcihiZXR3ZWVuKHJhbmssIDEsIDEwKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IocmFuayksIHkgPSBuX3JlYWRzKSkgKwogICAgZ2VvbV9jb2woZmlsbCA9IGN1c3RvbV9jb2xvcnNbMV0sIGFscGhhID0gMC43LCB3aWR0aCA9IDEpICsKICAgIGxhYnMoeSA9ICJuIHJlYWRzIiwgeCA9ICJiYXJjb2RlcyByYW5rZWQgYnkgYWJ1bmRhbmNlIikgKwogICAgZmFjZXRfd3JhcCh+c2FtcGxlLCBuY29sID0gNCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X3RvcDEwX2JhcmNvZGVzLCB3aWR0aCA9IGZpZ3dpZHRoLCBoZWlnaHQgPSBmaWdoZWlnaHQyKQpwcmludChwbG90X3RvcDEwX2JhcmNvZGVzKQpgYGAKCiMjIEN1bXVsYXRpdmUgcmVhZCBjb3VudCBkaXN0cmlidXRpb24gYW5kIGJhcmNvZGUgZGl2ZXJzaXR5CgotIGZpZ3VyZSBzaG93cyB0aGUgYmFyY29kZSBkaXZlcnNpdHkgYnkgcGxvdHRpbmcgZnJhY3Rpb24gb2YgcmVhZHMgKCUpIHZzIGZyYWN0aW9uIG9mIGJhcmNvZGVzICglKQotIHRoZSBpZGVhbCBsaWJyYXJ5IGhhcyBoaWdoIGRpdmVyc2l0eSBhbmQgZXF1YWwgZGlzdHJpYnV0aW9uIG9mIGJhcmNvZGVzIGZvciBpbml0aWFsIHRpbWUgcG9pbnRzCi0gc3VjaCBhIGRpc3RyaWJ1dGlvbiB3b3VsZCBmb2xsb3cgdGhlIGRpYWdvbmFsIGRhc2hlZCBncmV5IGxpbmUKLSBpZiByZWFkcyBwZXIgYmFyY29kZSAocmVkIGxpbmUpIGFyZSBub3Qgd2VsbCBkaXN0cmlidXRlZCwgYCUgb2YgcmVhZHNgICh5LWF4aXMpIHNob3dzIGEgc3RlZXAgYXNjZW50Ci0gdGhpcyBtZWFucyB2ZXJ5IGZldyBiYXJjb2RlcyBjb250cmlidXRlIHRvIGFsbW9zdCBhbGwgcmVhZHMKCmBgYHtyLCBmaWcud2lkdGggPSBmaWd3aWR0aCwgZmlnLmhlaWdodCA9IGZpZ2hlaWdodDIsIHdhcm5pbmcgPSBGQUxTRX0KZGZfYXVjIDwtIGRmX2NvdW50cyAlPiUKICAgIGRwbHlyOjphcnJhbmdlKHNhbXBsZSwgZGVzYyhuX3JlYWRzKSkgJT4lCiAgICBkcGx5cjo6Z3JvdXBfYnkoc2FtcGxlKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoCiAgICAgICAgcGNfYmFyY29kZXMgPSAxMDAgKiBzZXFfYWxvbmcobl9yZWFkcykgLyBuKCksCiAgICAgICAgcGNfcmVhZHMgPSAxMDAgKiBuX3JlYWRzIC8gKHN1bShuX3JlYWRzKSkKICAgICkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHBjX2JhcmNvZGVzID0gcm91bmQocGNfYmFyY29kZXMpKSAlPiUKICAgIGRwbHlyOjpncm91cF9ieShzYW1wbGUsIHBjX2JhcmNvZGVzKSAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUocGNfcmVhZHMgPSBzdW0ocGNfcmVhZHMpLCAuZ3JvdXBzID0gImRyb3BfbGFzdCIpICU+JQogICAgZHBseXI6Om11dGF0ZShwY19yZWFkcyA9IGN1bXN1bShwY19yZWFkcykpCgpwbG90X2N1bXVsYXRpdmVfcmVhZF9jb3VudCA8LSBkZl9hdWMgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBwY19iYXJjb2RlcywgeSA9IHBjX3JlYWRzLCBncm91cCA9IHNhbXBsZSkpICsKICAgIGdlb21fc3RlcChsaW5ld2lkdGggPSAxLjAsIGNvbG9yID0gY3VzdG9tX2NvbG9yc1sxXSkgKwogICAgZ2VvbV9hYmxpbmUoCiAgICAgICAgc2xvcGUgPSAxLCBpbnRlcmNlcHQgPSAwLCBsaW5ld2lkdGggPSAxLjAsCiAgICAgICAgbGluZXR5cGUgPSAyLCBjb2xvciA9IGdyZXkoMC41KQogICAgKSArCiAgICBsaW1zKHggPSBjKDAsIDEwMCksIHkgPSBjKDAsIDEwMCkpICsKICAgIGxhYnMoeCA9ICIlIG9mIGJhcmNvZGVzIiwgeSA9ICIlIG9mIHJlYWRzIikgKwogICAgZmFjZXRfd3JhcCh+c2FtcGxlLCBuY29sID0gNCkgKwogICAgY3VzdG9tX3RoZW1lKCkKCnNhdmVfcGxvdChwbG90X2N1bXVsYXRpdmVfcmVhZF9jb3VudCwgd2lkdGggPSBmaWd3aWR0aCwgaGVpZ2h0ID0gZmlnaGVpZ2h0MikKcHJpbnQocGxvdF9jdW11bGF0aXZlX3JlYWRfY291bnQpCmBgYAoKLSB0aGlzIHRhYmxlIHNob3dzIHRoZSBhcmVhIHVuZGVyIGN1cnZlIChBVUMpIGZvciB0aGUgbGluZSBwbG90IGFib3ZlCi0gYW4gQVVDIG9mIDAuNSBpcyBpZGVhbCwgYW4gQVVDIGFwcHJvYWNoaW5nIDEuMCBpcyBub3Qgb3B0aW1hbAotIHRoZSAnR2luaSBpbmRleCcgaXMgYSBzY29yZSBiZXR3ZWVuIDAgYW5kIDEgbWVhc3VyaW5nIHBvcHVsYXRpb24gZXF1YWxpdHkKLSBpdCBpcyBkZWZpbmVkIGFzIHRoZSBgKEFVQyAtIEFVQ19vcHRpbWFsKSAvIEFVQ19vcHRpbWFsYAotIGEgR2luaSBzY29yZSBvZiAwIGRlc2NyaWJlcyBhIHBlcmZlY3RseSBlcXVhbCwgYSBHaW5pIHNjb3JlIG9mIDEuMCBhIHBlcmZlY3RseSB1bmVxdWFsIGRpc3RyaWJ1dGlvbgoKYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0KY2FsY19hdWMgPC0gZnVuY3Rpb24oeCwgeSkgewogICAgc3VtKGRpZmYoeCkgKiAoaGVhZCh5LCAtMSkgKyB0YWlsKHksIC0xKSkpIC8gMgp9CmRmX2F1YyAlPiUKICAgIGRwbHlyOjpzdW1tYXJpemUoCiAgICAgICAgYXVjID0gY2FsY19hdWMocGNfYmFyY29kZXMsIHBjX3JlYWRzKS8xMDBeMiwKICAgICAgICBhdWNfb3B0aW1hbCA9IDAuNSwKICAgICAgICBnaW5pID0gKGF1YyAtIDAuNSkgLyAwLjUKICAgICkgJT4lCiAgICBtdXRhdGUocXVhbGl0eSA9IGNhc2Vfd2hlbigKICAgICAgICBnaW5pIDw9IDAuMzMgfiAibG93IGluZXF1YWxpdHkgKEcgPCAwLjMzKSIsCiAgICAgICAgZ2luaSA+IDAuMzMgJiBnaW5pIDw9IDAuNjYgfiAiaW50ZXJtZWRpYXRlIGluZXF1YWxpdHkgKDAuMzMgPCBHIDwgMC42NikiLAogICAgICAgIGdpbmkgPiAwLjY2IH4gImhpZ2ggaW5lcXVhbGl0eSAoRyA+IDAuNjYpIgogICAgKSkKYGBgCgoKIyMgU2FtcGxlIGFuZCByZXBsaWNhdGUgY29ycmVsYXRpb24gY29lZmZpY2VudCAoUikKCi0gZmlndXJlIHNob3dzIGhlYXQgbWFwIHdpdGggY29ycmVsYXRpb24gY29lZmZpY2llbnQgUiAoLTEgPCBSIDwgMSkKLSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBzaG93cyBob3cgc3Ryb25nbHkgcmVhZCBhYnVuZGFuY2UgaXMgY29ycmVsYXRlZAoKYGBge3IsIGZpZy53aWR0aCA9IDcuNSwgZmlnLmhlaWdodCA9IDcsIHdhcm5pbmcgPSBGQUxTRX0KZGZfY29ycmVsYXRpb24gPC0gZGZfY291bnRzICU+JQogICAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAic2FtcGxlIiwgdmFsdWVzX2Zyb20gPSAibl9yZWFkcyIpICU+JQogICAgZHBseXI6OnNlbGVjdCgtYygxOjIpKSAlPiUKICAgIGNvcigpCgpwbG90X3JlcGxpY2F0ZV9jb3JyZWxhdGlvbiA8LSBkZl9jb3JyZWxhdGlvbiAlPiUKICAgIGRwbHlyOjphc190aWJibGUoKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoc2FtcGxlMSA9IGNvbG5hbWVzKC4pKSAlPiUKICAgIHRpZHlyOjpwaXZvdF9sb25nZXIoCiAgICAgICAgY29scyA9ICFzYW1wbGUxLAogICAgICAgIG5hbWVzX3RvID0gInNhbXBsZTIiLCB2YWx1ZXNfdG8gPSAiY29yX2NvZWYiCiAgICApICU+JQogICAgZ2dwbG90KGFlcyh4ID0gc2FtcGxlMSwgeSA9IHNhbXBsZTIsIGZpbGwgPSBjb3JfY29lZikpICsKICAgIGdlb21fdGlsZSgpICsKICAgIGdlb21fdGV4dChjb2xvciA9IGdyZXkoMC40KSwgYWVzKGxhYmVsID0gcm91bmQoY29yX2NvZWYsIDIpKSkgKwogICAgY3VzdG9tX3RoZW1lKCkgKwogICAgbGFicyh0aXRsZSA9ICIiLCB4ID0gIiIsIHkgPSAiIikgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0ID0gMSkpICsKICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKAogICAgICAgIGNvbG91cnMgPSBjKGN1c3RvbV9jb2xvcnNbMV0sIGdyZXkoMC45KSwgY3VzdG9tX2NvbG9yc1syXSksCiAgICAgICAgbGltaXRzID0gYygtMSwgMSkKICAgICkKCndyaXRlLmNzdihkZl9jb3JyZWxhdGlvbiwgZmlsZSA9ICJjb3JyZWxhdGlvbl90YWJsZS5jc3YiKQpzYXZlX3Bsb3QocGxvdF9yZXBsaWNhdGVfY29ycmVsYXRpb24sIHdpZHRoID0gNy41LCBoZWlnaHQgPSA3KQpwcmludChwbG90X3JlcGxpY2F0ZV9jb3JyZWxhdGlvbikKYGBgCgojIyBTYW1wbGUgYW5kIHJlcGxpY2F0ZSBzaW1pbGFyaXR5IHdpdGggUENBCgotIHRoaXMgZmlndXJlIHNob3dzIHNhbXBsZSBzaW1pbGFyaXR5IHNpbWlsYXIgdG8gYWJvdmUgZmlndXJlCi0gdXNlcyBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIChQQ0EpIHRvIHJlZHVjZSB0aGUgbXVsdGlkaW1lbnNpb25hbCBkYXRhIHRvIDMgbWFpbiBkaW1lbnNpb25zCi0gcGxvdHRlZCBhcmUgcHJpbmNpcGFsIGNvbXBvbmVudCAxICh4LWF4aXMpLCAyICh5LWF4aXMpIGFuZCAzIChwb2ludCBzaXplKQotIHJlcGxpY2F0ZXMgZm9yIHNhbWUgc2FtcGxlcyBzaG91bGQgY2x1c3RlciB0b2dldGhlcgotIG91dGxpZXJzIHNob3VsZCBiZSBlYXNpbHkgdmlzaWJsZQoKYGBge3IsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3LCB3YXJuaW5nID0gRkFMU0V9CnBjYV9yZXN1bHQgPC0gZGZfY291bnRzICU+JQogICAgdGlkeXI6OnBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSAic2FtcGxlIiwgdmFsdWVzX2Zyb20gPSAibl9yZWFkcyIpICU+JQogICAgZHBseXI6OnNlbGVjdCgtYygxOjIpKSAlPiUKICAgIGFzLm1hdHJpeCgpICU+JQogICAgdCgpICU+JQogICAgcmVwbGFjZSguLCBpcy5uYSguKSwgMCkgJT4lCiAgICBwcmNvbXAoKQoKZGZfUENBIDwtIHBjYV9yZXN1bHQkeCAlPiUKICAgIGFzX3RpYmJsZShyb3duYW1lcyA9ICJzYW1wbGUiKQoKcGxvdF9yZXBsaWNhdGVfcGNhIDwtIGRmX1BDQSAlPiUKICAgIGdncGxvdChhZXMoeCA9IFBDMSwgeSA9IC1QQzIsIHNpemUgPSBQQzMsIGNvbG9yID0gc2FtcGxlLCBsYWJlbCA9IHNhbXBsZSkpICsKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjcpICsKICAgIGdlb21fdGV4dChzaXplID0gMi41LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgICBsYWJzKAogICAgICAgIHRpdGxlID0gIlBDQSwgZmlyc3QgdGhyZWUgcHJpbmNpcGFsIGNvbXBvbmVudHMiLAogICAgICAgIHN1YnRpdGxlID0gIlBvaW50IHNpemUgZW5jb2RlcyBQQzMiLCB4ID0gIlBDMSIsIHkgPSAiUEMyIgogICAgKSArCiAgICBjdXN0b21fdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCBhc3BlY3QucmF0aW8gPSAxKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JSYW1wUGFsZXR0ZShjdXN0b21fY29sb3JzKShucm93KGRmX1BDQSkpKSArCiAgICBndWlkZXMoc2l6ZSA9ICJub25lIikKCnNhdmVfcGxvdChwbG90X3JlcGxpY2F0ZV9wY2EsIHdpZHRoID0gNywgaGVpZ2h0ID0gNykKcHJpbnQocGxvdF9yZXBsaWNhdGVfcGNhKQpgYGAKCiMgUmVwb3J0IGluZm8KClRoZSB0ZW1wbGF0ZSBmb3IgdGhpcyByZXBvcnQgaXMgbG9jYXRlZCBpbiBgLi9uZi1jb3JlLWNyaXNwcmlzY3JlZW4vYmluL2NvdW50c19zdW1tYXJ5LlJtZGAuCgpEYXRlOiAyMDI0LTA0LTEwCgpBdXRob3I6IE1pY2hhZWwgSmFobiwgUGhECgpBZmZpbGF0aW9uczoKCi0gU2NpZW5jZSBGb3IgTGlmZSBMYWJvcmF0b3J5IChLVEgpLCBTdG9ja2hvbG0sIFN3ZWRlbgotIE1heC1QbGFuY2stVW5pdCBmb3IgdGhlIFNjaWVuY2Ugb2YgUGF0aG9nZW5zLCBCZXJsaW4sIEdlcm1hbnkKCiMgU2Vzc2lvbiBJbmZvCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAK